package geektime.spring.springbucks.customerservice;

import geektime.spring.springbucks.customerservice.model.Coffee;
import geektime.spring.springbucks.customerservice.model.NewOrderRequest;
import java.util.Arrays;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

@Component
@Slf4j
public class CustomerRunner implements ApplicationRunner {

  @Autowired
  private RestTemplate restTemplate;

  @Value("${waiter.service.url}")
  private String url;

  @Override
  public void run(ApplicationArguments args) throws Exception {

    readMenu();
    Long id = orderCoffee();
    queryOrder(id);

    Thread.sleep(Integer.MAX_VALUE);
  }

  private void readMenu() {
    ParameterizedTypeReference<List<Coffee>> ptr = new ParameterizedTypeReference<List<Coffee>>() {
    };
    ResponseEntity<List<Coffee>> list = restTemplate
        .exchange(url + "/coffee/", HttpMethod.GET, null, ptr);
    list.getBody().forEach(c -> log.info("Coffee :{}", c));
  }

  private Long orderCoffee() {
    NewOrderRequest orderRequest = NewOrderRequest.builder()
        .customer("Li Lei")
        .items(Arrays.asList("capuccino"))
        .build();

    RequestEntity<NewOrderRequest> request = RequestEntity
        .post(UriComponentsBuilder.fromUriString(url + "/order/").build().toUri())
        .body(orderRequest);

    ResponseEntity<Coffee> response = restTemplate.exchange(request, Coffee.class);
    log.info("Order Request Status Code:{}", response.getStatusCode());
    Long id = response.getBody().getId();
    log.info("Order Id:{}", id);
    return id;
  }

  private void queryOrder(Long id) {
    Coffee order = restTemplate
        .getForObject(url + "/order/{id}", Coffee.class, id);
    log.info("Order:{}", order);
  }
}
